
package at.fhj.ase.clientarch.client.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.fhj.ase.clientarch.common.User;
import at.fhj.ase.clientarch.common.util.EncryptorUtil;
import at.fhj.ase.clientarch.common.util.StringUtil;

/**
 * The application's login frame, managed by {@link ClientController}.
 * 
 * @author cja, sfe | www.fh-joanneum.at | Client Architectures and Design
 */
public final class LoginFrame extends JFrame implements ActionListener {
  private static final long serialVersionUID = 7280782429565524040L;

  private static final String ACTION_CMD_LOGIN = "actionCmdLogin";

  private final Logger logger = LoggerFactory.getLogger(getClass().getName());

  private JLabel jLabelUserName;
  private JLabel jLabelPassWord;
  private JTextField jTextFieldUserName;
  private JPasswordField jTextFieldPassWord;
  private JButton jBtnLogin;

  LoginFrame() {
    super();

    initGUIComponents();
  }

  private void initGUIComponents() {
    this.setName("Login");
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    jLabelUserName = new JLabel();
    jLabelPassWord = new JLabel();
    jTextFieldUserName = new JTextField();
    jTextFieldPassWord = new JPasswordField();
    jBtnLogin = new JButton();

    jLabelUserName.setText("Username:");
    jLabelUserName.setName("jLabelUserName");

    jLabelPassWord.setText("Password:");
    jLabelPassWord.setName("jLabelPassWord");

    // tempoarily values in textfields
    jTextFieldUserName.setText("carina");
    jTextFieldUserName.setName("jTextFieldUserName");

    jTextFieldPassWord.setText("carinapw");
    jTextFieldPassWord.setName("jTextFieldPassWord");

    jBtnLogin.setText("Login");
    jBtnLogin.setName("jBtnLogin");
    jBtnLogin.addActionListener(this);
    jBtnLogin.setActionCommand(ACTION_CMD_LOGIN);
    
    //TODO add key listener for comfortability

    javax.swing.GroupLayout thisLayout = new javax.swing.GroupLayout(this.getContentPane());
    this.getContentPane().setLayout(thisLayout);
    thisLayout
              .setHorizontalGroup(thisLayout
                                            .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                              .addGroup(
                                                        thisLayout
                                                                  .createSequentialGroup()
                                                                    .addContainerGap()
                                                                    .addGroup(
                                                                              thisLayout
                                                                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                                                          .addGroup(
                                                                                                    thisLayout
                                                                                                              .createSequentialGroup()
                                                                                                                .addComponent(jLabelUserName)
                                                                                                                .addPreferredGap(
                                                                                                                                 javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                                                                                .addComponent(
                                                                                                                              jTextFieldUserName,
                                                                                                                              javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                                                              143,
                                                                                                                              javax.swing.GroupLayout.PREFERRED_SIZE))
                                                                                          .addGroup(
                                                                                                    javax.swing.GroupLayout.Alignment.TRAILING,
                                                                                                    thisLayout
                                                                                                              .createSequentialGroup()
                                                                                                                .addComponent(jLabelPassWord)
                                                                                                                .addPreferredGap(
                                                                                                                                 javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                                                                                                                 12, Short.MAX_VALUE)
                                                                                                                .addGroup(
                                                                                                                          thisLayout
                                                                                                                                    .createParallelGroup(
                                                                                                                                                         javax.swing.GroupLayout.Alignment.LEADING)
                                                                                                                                      .addComponent(jBtnLogin)
                                                                                                                                      .addComponent(
                                                                                                                                                    jTextFieldPassWord,
                                                                                                                                                    javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                                                                                    143,
                                                                                                                                                    javax.swing.GroupLayout.PREFERRED_SIZE))))
                                                                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
    thisLayout.setVerticalGroup(thisLayout
                                          .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addGroup(
                                                      thisLayout
                                                                .createSequentialGroup()
                                                                  .addContainerGap()
                                                                  .addGroup(
                                                                            thisLayout
                                                                                      .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                                                        .addComponent(jLabelUserName)
                                                                                        .addComponent(jTextFieldUserName,
                                                                                                      javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                                      javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                                      javax.swing.GroupLayout.PREFERRED_SIZE))
                                                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                  .addGroup(
                                                                            thisLayout
                                                                                      .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                                                        .addComponent(jLabelPassWord)
                                                                                        .addComponent(jTextFieldPassWord,
                                                                                                      javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                                      javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                                      javax.swing.GroupLayout.PREFERRED_SIZE))
                                                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE)
                                                                  .addComponent(jBtnLogin)
                                                                  .addContainerGap()));

  }

  private final String getPasswordOfTextField() {
    char[] password = jTextFieldPassWord.getPassword();
    jTextFieldPassWord.setText(""); // reset the password (tested)

    // only check the length here as the textfield will never return null, only empty strings
    return StringUtil.checkLengthDefaults(String.valueOf(password));
  }

  private final String getUsernameOfTextField() {
    // only check the length here as the textfield will never return null, only empty strings
    return StringUtil.checkLengthDefaults(jTextFieldUserName.getText());
  }

  private final User createUserOutofTextFields() {
    return new User(getUsernameOfTextField(), EncryptorUtil.toString(EncryptorUtil.toMD5(getPasswordOfTextField())));
  }

  @Override
  public final void actionPerformed(ActionEvent e) {
    final String actionCommand = e.getActionCommand();
    if (actionCommand.equals(ACTION_CMD_LOGIN)) { //TODO maybe add additional checks here
      onLogin();
    }
  }

  private void onLogin() {
    User user = null;
    try {
      user = createUserOutofTextFields();
    } catch (IllegalArgumentException iae) {
      logger.error("Troubles creating a user: ", iae);
      JOptionPane.showMessageDialog(this, "User and/or password invalid (length > " + StringUtil.DEFAULT_STRING_LENGTH_MIN + ")", "User authentication",
                                    JOptionPane.ERROR_MESSAGE);
      return;
    }

    try {
      ClientController.INSTANCE.authenticateUserStartMainGUI(user);
    } catch (ClassNotFoundException e) {
      logger.error("Could not find class: ", e);
    } catch (SQLException e) {
      logger.error("SQL problem: ", e);
    }
  }
}
